﻿using System;
using System.Collections.Generic;
using HalconDotNet;

using System.Linq;

using System.Xml.Linq;
using System.Xml.XPath;

using System.IO;

namespace inspect
{

    public class Moudle
    {
        public string ModelName;
        public HTuple hv_ModelID;
        public Moudle(string tpath,string tName)
        {
            ModelName = tName;
            HOperatorSet.ReadShapeModel(tpath+"HD/shap/"+tName+".shm", out hv_ModelID);
        }
    }
    public class CompData
    {
        public int DBNo;//决定model
        public string Type;//决定检测方法
        public string Name;
        public string MoudleName;
        public string Silk;

        public HTuple ModelID;
        public string CompNo;//ymhXML中的CompNo，贴装通过此属性来与元件关联   

        public int ParamNo1;
        public int ParamNo2;
        public int ResultNo;
        public int[] ParamS1;
        public int[] ParamS2;

        public CompData(string tPath, string tCompNo,string[] tParams)
        {
            CompNo = tCompNo;
            DBNo = int.Parse(tParams[0]);
            Type = tParams[1];
            Name = tParams[2];
            MoudleName = tParams[3];
            Silk = tParams[4];
            ParamNo1 = int.Parse(tParams[5]);
            ParamNo2 = int.Parse(tParams[6]);
            ResultNo = int.Parse(tParams[7]);

            ParamS1 = new int[ParamNo1];
            for (int tInd = 0; tInd < ParamNo1; tInd++)
            {
                ParamS1[tInd] = int.Parse(tParams[tInd + 8]);
            }

            ParamS2 = new int[ParamNo2];
            for (int tInd = 0; tInd < ParamNo2; tInd++)
            {
                ParamS2[tInd] = int.Parse(tParams[tInd + 8 + ParamNo1]);
            }
        }
    }
    public class DataS
    {
        string fPath = "H:/";
        string dbFile = "HD/db/paramDB.txt";

        List<CompData> LiCompS = new List<CompData>();
        List<Moudle> LiMoudleS = new List<Moudle>();
        //MountData[] MountS; 
        List<MountData> LiMountS = new List<MountData>();

        //通过mount 取器件数据
        public bool GetCompData(ref MountData tMount, ref CompData tComp)
        {
            string tNo = tMount.CompNo;
            tComp = LiCompS.Find(x => x.CompNo == tNo);
            if (tComp != null)
                return true;
            else
                return false;
        }
        //通过mount Name取器件数据
        public bool GetCompData(string tName,ref MountData tMount,ref CompData tComp)
        {
            tMount = LiMountS.Find(x => x.Name == tName);
            
            if (tMount != null)
            {
                return GetCompData(ref tMount, ref tComp);
                //string tNo = tMount.CompNo;
                //tComp = LiCompS.Find(x => x.CompNo == tNo);
                //if (tComp != null)
                //    return true;
                //else
                //    return false;
            }
            else
                return false;
        }

        //设置器件数据
        public void SetCompData(string tPath, string tCompNo, string[] tParams)
        {
            CompData clCompData = new CompData(tPath, tCompNo, tParams);
            HTuple tModelID;
            
            string tMoudleName = clCompData.MoudleName;
            getMoudle(tPath,tMoudleName,out tModelID);
            clCompData.ModelID = tModelID;

            LiCompS.Add(clCompData);
        }

        //使用Name从list中取Moudle，如果不存在执行添加
        public void getMoudle(string tpath, string tMoudleName, out HTuple tModelID)
        {
            Moudle ttemp = LiMoudleS.Find(x => x.ModelName == tMoudleName);
            if (ttemp != null)
            {
                ttemp = LiMoudleS.Find(x => x.ModelName == tMoudleName);
                tModelID = ttemp.hv_ModelID;
            }
            else
            {
                Moudle tMoudle = new Moudle(tpath, tMoudleName);
                tModelID = tMoudle.hv_ModelID;
                LiMoudleS.Add(tMoudle); 
            }
        }

        //从paramDB查找存在的tNo，写入CompDatas
        public void LoadParamDB(string tPath, string tDBNo, string tCompNo)
        {
            string[] tParams = { };
            StreamReader reader = new StreamReader(tPath + dbFile);
            string[] words = reader.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            try
            {
                tParams = (from ln in words
                           let word = ln.Split('\t')
                           where word[0] == tDBNo
                           select word).Single();
            }
            catch (System.InvalidOperationException e)
            {
                //continue;
                return;
            }
            SetCompData(tPath, tCompNo, tParams);
        }

        //读xml 初始化元件数据
        public void LoadMntXML(string mntFile)
        {
            int exec = 1;//ymh xml 跳过标志
            string tDBNo, tNo;
            //int[] execList;
            int tPartNo;
            //string[] tParams = { };

            //读Components,先找DatabaseNo！=0
            XElement xElement = XElement.Load(mntFile);
            IEnumerable<XElement> comps = xElement.XPathSelectElements("./Components/Component[@DatabaseNo!='0']");

            foreach (XElement comp in comps)
            {
                //Console.WriteLine("DatabaseNo:{0}", comp.Attribute("DatabaseNo").Value);
                tDBNo = comp.Attribute("DatabaseNo").Value;
                tNo = comp.Attribute("No").Value;
                LoadParamDB(fPath, tDBNo, tNo);
            }

            //读贴装数据
            //先从Optimized中确定是否跳过器件OptimizedVariations
            //然后再从Mounts中读取器件坐标
            IEnumerable<XElement> OptimizedVariations = xElement.XPathSelectElements("./OptimizedVariations/MountVariation/Optimized/Mount[@Exec='0']");
            tPartNo = OptimizedVariations.Count();
            if ( tPartNo > 0)
            {
                //string[,] execList = new string[tPartNo, 2];
                List<string> execList = new List<string>();
                foreach (XElement optimized in OptimizedVariations)
                {
                    execList.Add(optimized.Attribute("No").Value);
                }

                IEnumerable<XElement> Mounts = xElement.XPathSelectElements("./PatternDatas/Mounts/Mount");
                foreach (XElement mount in Mounts)
                {
                    tDBNo = mount.Attribute("No").Value;
                    if(execList.Exists(x => x == tDBNo))
                    {
                        MountData tMount = new MountData() { };
                        Postion tPos = new Postion() { };
                        tPos.X = float.Parse(mount.Attribute("X").Value);
                        tPos.Y = float.Parse(mount.Attribute("Y").Value);
                        tPos.R = float.Parse(mount.Attribute("R").Value);

                        tMount.MonutNo = int.Parse(mount.Attribute("No").Value);
                        tMount.CompNo = mount.Attribute("CompNum").Value;
                        tMount.Name = mount.Attribute("Comment").Value;
                        tMount.Pos = tPos;
                        LiMountS.Add(tMount);
                    }
                }
            }
        }
    }
}

